﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Common
{
    /// <summary>
    ///     This is the hard of the project. A class that maps a number to a short text encoding of that number
    ///     Of course we also need to decode that text into a number.
    /// </summary>
    public static class ShortUrlEncoder
    {
        // url中允许的字符
        private const string urlChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-";

        // urlChars的长度，还用于编码的base
        private static readonly long urlCharsLength = urlChars.Length;

        // 将每个urlChars中的字符映射到对应的位置上
        private static readonly Dictionary<char, int> reverse = new Dictionary<char, int>();

        static ShortUrlEncoder()
        {
            // 设置转换字典
            for (int i = 0; i < urlChars.Length; i++)
                reverse.Add(urlChars[i], i);
        }

        /// <summary>
        /// 将数字编码为短字符串
        /// 如 将 103892092010 转为 "Xiy"
        /// </summary>
        /// <param name="number">要编码的数字</param>
        /// <returns>编码生成的短文本</returns>
        public static string Encode(long number)
        {
            StringBuilder sb = new StringBuilder();
            int remainder;

            while (number > 0)
            {
                remainder = (int)(number % urlCharsLength);
                number = number / urlCharsLength;

                sb.Append(urlChars[remainder]);
            };

            return sb.ToString();
        }

        ///// <summary>
        ///// 将字符串解码为数字
        ///// 如 将 "Xiy" 转为 103892092010
        ///// </summary>
        ///// <param name="text">要解码的文本</param>
        ///// <returns>短文本所表示的数字</returns>
        //[Obsolete("Just search the db for the short url, leaving here for testing purposes")]
        //public long Decode(string text)
        //{
        //    long result = 0;

        //    for (int i = 0; i < text.Length; i++)
        //    {
        //        int charIndex = reverse[text[i]];
        //        var powResult = (long)Math.Pow(urlCharsLength, i);
        //        result += charIndex * powResult;
        //    }

        //    return result;
        //}
    }

}
